import { PermissionsAndroid, Linking, ToastAndroid } from "react-native";
import fso from "@/utils/FileOperate/operate";
import navigation from "@/utils/navigation";

import type { Permission } from "react-native";

// 设置权限封装
export const getPermissions = async (per: Permission, msg = "请设置权限") => {
  // 判断是否有权限
  const isFlog = await PermissionsAndroid.check(per);
  if (!isFlog) {
    const res = await PermissionsAndroid.request(per);
    // 没有权限直接跳转到应用设置界面
    if ([PermissionsAndroid.RESULTS.DENIED, PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN].includes(res)) {
      ToastAndroid.show(msg, ToastAndroid.LONG);
      await Linking.openSettings();
    }
  }
};

// 防抖
export const debounce = (fn: (...firsh: any[]) => any, delay: number) => {
  let timer: number;
  let result: any;
  return (...args: any[]) => {
    clearTimeout(timer);
    // @ts-ignore
    timer = setTimeout(() => {
      result = fn(...args);
    }, delay);
    return result;
  };
};

// async 阻塞
export const sleep = (delay: number) => new Promise<void>(resolve => setTimeout(() => resolve(), delay));

// 解析版本号为数字 1.2.3 -> 123
export const parseVersion = (version: string) => {
  let ret;
  if (version.indexOf(".") !== -1) {
    ret = parseInt(version.replace(/\./g, ""));
  } else {
    ret = parseFloat(version);
  }
  return ret;
};

type OptType<T extends object = any> = {
  /** 查询数据的key */
  key: string;
  /** 数据 */
  data: T[];
  /** 自定义对比函数 */
  compareFn: (val: T) => boolean;
};

// 递归查询数据
export const recursionFind = <T extends object = any>(option: OptType<T>) => {
  const result: T[] = [];

  // 查找函数
  const findFn = (opt: OptType<T>) => {
    for (let i = 0; i < opt.data.length; i++) {
      const val = opt.data[i] as T;
      // 比较
      const isFlag = opt.compareFn(val);

      if (isFlag) {
        // 清除子项
        // (val as any)[opt.key] = [];
        result.push(val);
      }

      const target = (val as any)[opt.key];
      if (target) {
        // console.log("target: ", target);
        // 继续递归
        findFn({
          key: option.key,
          compareFn: option.compareFn,
          data: target
        });
      }
    }
  };

  findFn(option);

  return result;
};

/** 查询url解析成obj */
export const params2Obj = <T extends { [k in string]: any }>(opt: {
  /** url */
  str: string;
  /** 是否解码键和值 */
  decode: boolean;
}): T | null => {
  const obj = {} as T;

  const symbol = "?";

  if (opt.str.indexOf(symbol) !== -1) {
    const list = opt.str.split(symbol);
    if (list.length === 1) {
      return null;
    } else {
      list.shift();
      list
        .join(symbol)
        .split("&")
        .forEach(kv => {
          const [k, v] = kv.split("=");
          if (opt.decode) {
            // @ts-ignore
            obj[decodeURI(k)] = decodeURI(v);
          } else {
            // @ts-ignore
            obj[k] = v;
          }
        });
    }

    return obj;
  } else {
    return null;
  }
};

/** 跳转到播放页面 */
export const gotoVideoDisplayPage = () => {
  const res = navigation.getRouter();
  // 不在播放页面则跳转
  if (res) {
    if (res.name !== "VideoDisplay") {
      fso.info("设备不在播放页面跳转到播放页面");
      navigation.replace("VideoDisplay");
    } else {
      fso.info("设备已经在播放页面了, 不进行跳转");
    }
  } else {
    // TODO app重启时会跳转不过去
    navigation.replace("VideoDisplay");
    fso.info("设备不在播放页面跳转到播放页面");
  }
};

// 生成uuid
export const genUUID = () => {
  return "xxxx-xxxx-4xxx-yxxx".replace(/[xy]/g, c => {
    const r = (Math.random() * 16) | 0,
      v = c == "x" ? r : (r & 0x3) | 0x8;
    return v.toString(16);
  });
};

/** 数据类型, 必须指定 task */
type SyncTaskType<T = any> = {
  /** 异步任务 */
  task: () => Promise<T>;

  /** 其它参数 */
  [k: string]: any;
};

/** 执行并发操作, 可以控制 Promise 的并发数 */
export const syncTask = <T = any>(opt: {
  /** 异步任务队列 */
  taskList: SyncTaskType<T>[];
  /** 并发数 */
  limit: number;
  /** 任务执行成功回调 */
  onSuccess?: (res: T, item: SyncTaskType<T>) => void;
  /** 任务执行失败回调 */
  onError?: (error: unknown, item: SyncTaskType<T>) => void;
  /** 任务执行完成回调 */
  onFinally?: (item: SyncTaskType<T>) => void;
}): Promise<{
  /** 成功的返回值 */
  successList: T[];
  /** 失败的返回值 */
  errorList: unknown[];
}> => {
  return new Promise(resolve => {
    // 正在运行的任务
    const runningPool: SyncTaskType[] = [];
    // 等待运行的任务
    const waitinggPool: SyncTaskType[] = [];
    // 成功运行返回值
    const successList: T[] = [];
    // 失败运行返回值
    const errorList: T[] = [];

    // 运行任务
    const walker = (item: SyncTaskType) => {
      item
        .task()
        .then(res => {
          opt.onSuccess && opt.onSuccess(res, item);
          successList.push(res);
        })
        .catch(err => {
          opt.onError && opt.onError(err, item);
          errorList.push(err);
        })
        .finally(() => {
          opt.onFinally && opt.onFinally(item);

          // 任务出栈
          runningPool.shift();

          if (waitinggPool.length) {
            // 拿出下一个任务
            const next = waitinggPool.shift();
            if (next) {
              // 继续入栈任务
              runningPool.push(next);
              // 继续运行
              walker(next);
            }
          } else {
            // 当前没有正在运行的任务
            if (runningPool.length === 0) {
              resolve({
                successList,
                errorList
              });
            }
          }
        });
    };

    // 开始执行
    opt.taskList.forEach(item => {
      // 当前正在执行的任务小于给定的并发数
      if (runningPool.length < opt.limit) {
        // 入栈任务
        runningPool.push(item);
        // 开始执行
        walker(item);
      } else {
        // 超过最大并发, 保存到等待运行任务中
        waitinggPool.push(item);
      }
    });
  });
};
